#include <ani.h>
#include <array>
#include <iostream>
#include <vector>

std::string toString(ani_env *env, ani_string ani_str)
{
    ani_size strSize;
    env->String_GetUTF8Size(ani_str, &strSize);

    std::vector<char> buffer(strSize + 1); // +1 for null terminator
    char *utf8_buffer = buffer.data();

    // String_GetUTF8 Supportted by https://gitee.com/openharmony/arkcompiler_runtime_core/pulls/3416
    ani_size bytes_written = 0;
    env->String_GetUTF8(ani_str, utf8_buffer, strSize + 1, &bytes_written);

    utf8_buffer[bytes_written] = '\0';
    std::string content = std::string(utf8_buffer);
    return content;
}

template<typename T>
void compareAndReport(const T& param1, const T& param2, const std::string& errorMessage) {
    if (param1 != param2) {
        std::cerr << errorMessage << std::endl;
        return;
    }
    // 如果需要处理相等的情况，可以在这里添加相应的逻辑
}

template<typename T>
void compareAndReport(const T& param1, const T& param2, const std::string& errorMessage, const std::string& message) {
    if (param1 != param2) {
        std::cerr << errorMessage << std::endl;
        return;
    }
    else {
        std::cerr << message << std::endl;
        return;
    }
}

ani_int bindFunc(ani_env *env, [[maybe_unused]] ani_object object, ani_string paramObj)
{
    ani_int getx  = 99;
    std::string str = toString(env, paramObj);
    std::cout<<str<<std::endl;
    return getx;
}



ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
{
    
    std::cerr << "Entry ANI_Constructor" << std::endl;
    ani_env *env;
    if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env))
    {
        std::cerr << "Unsupported ANI_VERSION_1" << std::endl;
        return ANI_ERROR;
    }

    static const char *className = "L@depence/ns;";

    ani_class cls;
    if (ANI_OK != env->FindClass(className, &cls))
    {
        std::cerr << "Not found '" << className << "'" << std::endl;
        return ANI_ERROR;
    }

    ani_namespace clsns;
    if (ANI_OK != env->FindNamespace(className, &clsns))
    {
        std::cerr << "Not found ns '" << className << "'" << std::endl;
        return ANI_ERROR;
    }


    std::array methods = {
        ani_native_function{"getInt", "Lstd/core/String;:I", reinterpret_cast<void *>(bindFunc)},
    };

    std::cout << "Start bind native methods to '" << className << "'" << std::endl;
    ani_status rs;
    rs = env->Class_BindNativeMethods(cls, methods.data(), methods.size());
    if ( rs != ANI_OK )
    {
        std::cerr << "Cannot bind native methods to '" << className << "'" << std::endl;
        return rs;
    };
    std::cout << "Finish bind native methods to '" << className << "'" << std::endl;

    *result = ANI_VERSION_1;
    return ANI_OK;
}